package com.jiangxjsy.admin.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jiangxjsy.admin.client.EmailClient;
import com.jiangxjsy.admin.mapper.AdminUserMapper;
import com.jiangxjsy.admin.property.JwtProperty;
import com.jiangxjsy.admin.service.*;
import com.jiangxjsy.admin.support.AdminUserSupport;
import com.jiangxjsy.core.common.UserStatus;
import com.jiangxjsy.core.constant.BasicConstant;
import com.jiangxjsy.core.exception.AuthorizationException;
import com.jiangxjsy.core.exception.BasicException;
import com.jiangxjsy.core.exception.NoLoginException;
import com.jiangxjsy.core.jwt.JwtCore;
import com.jiangxjsy.core.page.BasePage;
import com.jiangxjsy.core.security.PasswordEncoder;
import com.jiangxjsy.core.security.kit.Algorithm;
import com.jiangxjsy.core.security.kit.SaltGenerator;
import com.jiangxjsy.core.system.SystemCore;
import com.jiangxjsy.core.wrap.ResultCode;
import com.jiangxjsy.model.admin.bo.AdminUserBO;
import com.jiangxjsy.model.admin.entity.AdminConfig;
import com.jiangxjsy.model.admin.entity.AdminRole;
import com.jiangxjsy.model.admin.entity.AdminUser;
import com.jiangxjsy.model.admin.entity.AdminUserConfig;
import com.jiangxjsy.model.admin.vo.*;
import com.jiangxjsy.model.authorization.bo.AdminUserStatusBO;
import com.jiangxjsy.model.core.entity.UserMeta;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.InvocationTargetException;
import java.sql.Timestamp;
import java.time.Instant;
import java.util.*;
import java.util.stream.Collectors;

/**
 * wukong-crm-master
 * 蒋胜宇
 * 2025/6/6 19:26
 */

@Service
public class AdminUserServiceImpl implements AdminUserService {
    @Resource
    private AdminUserMapper adminUserMapper;

    @Resource
    private AdminUserRoleService adminUserRoleService;

    @Resource
    private AdminUserConfigService adminUserConfigService;

    @Resource
    private AdminDeptService adminDeptService;

    @Resource
    private AdminConfigService adminConfigService;

    @Resource
    private AdminUserHisTableService adminUserHisTableService;

    @Resource
    private AdminRoleService adminRoleService;

    @Resource
    private EmailClient emailClient;

    @Resource
    private AdminUserSupport adminUserSupport;

    @Resource
    private JwtProperty jwtProperty;

    @Resource
    private PasswordEncoder passwordEncoder;

    /**
     * 根据用户名查询用户信息
     *
     * @param username 用户名
     * @return 用户信息
     */
    @Override
    public List<Map<String, Object>> findByUsername(String username) {
        List<Map<String, Object>> userInfoList = adminUserMapper.selectByUsername(username);
        userInfoList.forEach(userInfo -> {
            userInfo.put("superUserId", SystemCore.getSuperUser());
            userInfo.put("superRoleId", SystemCore.getSuperRole());
        });
        return userInfoList;
    }

    /**
     * 根据用户 id 查询用户角色 id 列表
     *
     * @param userId 用户 id
     * @return 角色 id 列表
     */
    @Override
    public List<Integer> queryUserRoleIds(Long userId) {
        return adminUserRoleService.queryUserRoleIds(userId);
    }

    /**
     * 设置用户状态
     *
     * @param adminUserStatusBO 用户状态
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void setUserStatus(AdminUserStatusBO adminUserStatusBO) {
        for (Long id : adminUserStatusBO.getIds()) {
            if (UserStatus.DISABLE.getStatus().equals(adminUserStatusBO.getStatus())) {
                if (id.equals(SystemCore.getSuperUser())) {
                    throw new BasicException(ResultCode.AdminResultCode.ADMIN_SUPER_USER_DISABLED_ERROR);
                }
                adminUserSupport.userExit(id, null);
            } else if (UserStatus.NORMAL.getStatus().equals(adminUserStatusBO.getStatus())) {
                Integer roleCount = adminUserRoleService.queryCountByUserId(id);
                if (roleCount == 0) {
                    throw new BasicException(ResultCode.AdminResultCode.ADMIN_USER_NOT_ROLE_ERROR);
                }
                AdminUser adminUser = adminUserMapper.selectByUserId(id);
                if (adminUser.getDeptId() == null) {
                    throw new BasicException(ResultCode.AdminResultCode.ADMIN_USER_NOT_DEPT_ERROR);
                }
            }
            Integer ignore = adminUserMapper.updateStatusByUserId(id, adminUserStatusBO.getStatus());
        }
    }

    /**
     * 激活用户
     *
     * @param adminUserStatusBO 用户状态
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void activateUser(AdminUserStatusBO adminUserStatusBO) {
        for (Long id : adminUserStatusBO.getIds()) {
            if (UserStatus.DISABLE.getStatus().equals(adminUserStatusBO.getStatus())) {
                if (id.equals(SystemCore.getSuperUser())) {
                    throw new BasicException(ResultCode.AdminResultCode.ADMIN_SUPER_USER_DISABLED_ERROR);
                }
                adminUserSupport.userExit(id, null);
            } else if (UserStatus.NORMAL.getStatus().equals(adminUserStatusBO.getStatus())) {
                Integer roleCount = adminUserRoleService.queryCountByUserId(id);
                if (roleCount == 0) {
                    throw new BasicException(ResultCode.AdminResultCode.ADMIN_USER_NOT_ROLE_ERROR);
                }
                AdminUser adminUser = adminUserMapper.selectByUserId(id);
                if (adminUser.getDeptId() == null) {
                    throw new BasicException(ResultCode.AdminResultCode.ADMIN_USER_NOT_DEPT_ERROR);
                }
            }
            Integer ignore = adminUserMapper.updateStatusByUserId(id, adminUserStatusBO.getStatus());
        }
    }

    /**
     * 查询系统状态
     *
     * @return 系统状态
     */
    @Override
    public Integer querySystemStatus() {
        Long count = adminUserMapper.selectCount();
        return count > 0 ? 1 : 0;
    }

    /**
     * 根据用户 ID 查询用户信息
     *
     * @param userId 用户 ID
     * @return 用户信息
     */
    @Override
    public AdminUser queryByUserId(Long userId) {
        return adminUserMapper.selectByUserId(userId);
    }

    /**
     * 查询登录用户信息
     *
     * @param request 请求
     * @param response 响应
     * @return 登录用户信息
     */
    @Override
    public AdminSuperUserVO queryLoginUser(HttpServletRequest request, HttpServletResponse response) {
        String token = request.getHeader(BasicConstant.TOKEN_NAME);
        UserMeta userMeta;
        try {
            userMeta = new JwtCore<>(UserMeta.class).analyzeToken(token, jwtProperty.getPublicKey());
        } catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException | InstantiationException e) {
            throw new AuthorizationException(ResultCode.AuthorizationResultCode.AUTHORIZATION_LOGIN_ERR);
        }
        Long userId = userMeta.getUserId();
        AdminUser user = queryByUserId(userId);
        if (user == null) {
            throw new NoLoginException();
        }

        AdminSuperUserVO adminUser = BeanUtil.copyProperties(user, AdminSuperUserVO.class);
        adminUser.setIsAdmin(adminUserSupport.isAdmin(userId));

        AdminUserConfig userConfig = adminUserConfigService.queryUserConfigByUserIdAndName(
                userId, "readNotice");
        adminUser.setIsReadNotice(Math.toIntExact(userConfig != null ? userConfig.getStatus() : 0));
        adminUser.setPassword(null);

        String deptName = adminDeptService.getNameByDeptId(Long.valueOf(adminUser.getDeptId()));
        adminUser.setDeptName(deptName);
        adminUser.setParentName(adminUserSupport.getParentName(adminUser.getParentId()));

        AdminConfig config = adminConfigService.queryConfigByName("email");
        if (config != null && config.getStatus() == 1) {
            Integer data = emailClient.getEmailId(adminUser.getUserId()).getData();
            adminUser.setEmailId(data);
        }

        AdminUserConfig userConfigByName = adminUserConfigService.queryUserConfigByUserIdAndName(
                userId, "InitUserConfig");
        if(userConfigByName != null){
            adminUser.setServerUserInfo(JSON.parseObject(userConfigByName.getValue()));
        }

        return adminUser;
    }

    /**
     * 查询企业下所有用户
     * @param adminUserBO 业务对象，查询参数
     * @return 用户列表分页对象
     */
    @Override
    public BasePage<AdminUserVO> queryUserList(AdminUserBO adminUserBO) {
        if (adminUserBO == null) {
            BasePage<AdminUserVO> userBasePage = new BasePage<>();
            List<AdminUser> adminUsers = adminUserMapper.selectNonSuperUsers(SystemCore.getSuperUser());
            List<AdminUserVO> adminUserVOList = adminUsers.stream().map(
                    adminUser -> adminUserSupport.convertAdminUserToVO(adminUser, 2)
            ).collect(Collectors.toList());

            AdminUser adminSuperUser = adminUserMapper.selectByUserId(SystemCore.getSuperUser());
            adminUserVOList.add(0, adminUserSupport.convertAdminUserToVO(adminSuperUser, 0));
            BasePage<AdminUserVO> ignore = userBasePage.setRecords(adminUserVOList);
            return userBasePage;
        }

        Long deptOwnerUserId = null;
        adminUserBO.setUserId(SystemCore.getSuperUser());
        if (adminUserBO.getDeptId() != null) {
            List<Integer> list;
            if (Objects.equals(adminUserBO.getIsNeedChild(), 1)) {
                list = adminDeptService.queryChildDept(adminUserBO.getDeptId());
            } else {
                list = new ArrayList<>();
            }
            list.add(adminUserBO.getDeptId());
            adminUserBO.setDeptIdList(list);
            deptOwnerUserId = adminDeptService.queryByDeptId(Long.valueOf(adminUserBO.getDeptId())).getOwnerUserId();
            adminUserBO.setDeptOwnerUserId(deptOwnerUserId);
        }

        BasePage<AdminUserVO> basePage = new BasePage<>();
        List<AdminUserVO> adminUserVOS = adminUserMapper.selectUserList(adminUserBO.parse(), adminUserBO);
        basePage.setList(adminUserVOS);

        if (deptOwnerUserId != null) {
            if (adminUserBO.getPage() == 1) {
                for (AdminUserVO adminUserVO : basePage.getRecords()) {
                    if (Objects.equals(adminUserVO.getUserId(), deptOwnerUserId)) {
                        adminUserVO.setUserIdentity(1);
                    }
                }
            }
        } else {
            if (adminUserBO.getPage() == 1) {
                for (AdminUserVO adminUserVO : basePage.getRecords()) {
                    if (Objects.equals(adminUserVO.getUserId(), SystemCore.getSuperUser())) {
                        adminUserVO.setUserIdentity(0);
                    }
                }
            }
        }

        List<Long> longs = adminUserHisTableService.queryUserIdsByHisTable(1L);
        basePage.getRecords().forEach(adminUserVO -> {
            if(longs.contains(adminUserVO.getUserId())){
                adminUserVO.setHisTable(1);
            }
            List<AdminRole> adminRoleList = adminRoleService.queryRoleListByUserId(adminUserVO.getUserId());
            adminUserVO.setRoleId(adminRoleList.stream().map(adminRole -> adminRole.getRoleId().toString()).collect(Collectors.joining(",")));
            adminUserVO.setRoleName(adminRoleList.stream().map(AdminRole::getRoleName).collect(Collectors.joining(",")));
        });

        return basePage;
    }

    /**
     * 查询用户数量
     *
     * @return 用户数量
     */
    @Override
    public JSONObject countUserByLabel() {
        JSONObject jsonObject = new JSONObject();
        jsonObject
                .fluentPut("allUserCount", adminUserMapper.countUserByLabel(0, null))
                .fluentPut("addNewlyCount", adminUserMapper.countUserByLabel(1, null))
                .fluentPut("activateCount", adminUserMapper.countUserByLabel(null, 1))
                .fluentPut("inactiveCount", adminUserMapper.countUserByLabel(2, null))
                .fluentPut("disableCount", adminUserMapper.countUserByLabel(3, null));
        return jsonObject;
    }

    /**
     * 查询部门下所有用户
     *
     * @param deptId 部门 id
     * @param isAllUser 是否查询所有用户
     * @return 部门的用户列表
     */
    @Override
    public DeptUserListVO queryDeptUserList(Integer deptId, boolean isAllUser) {
        DeptUserListVO deptUserListVO = new DeptUserListVO();
        List<DeptVO> deptList = adminDeptService.queryDeptUserList();
        List<DeptVO> ignore = adminUserSupport.createTree(deptId, deptList);

        List<HrmSimpleUserVO> userList;
        if (isAllUser) {
            userList = adminUserMapper.selectSimpleUserByDeptId(deptId);
        } else {
            userList = adminUserMapper.selectSimpleUserByDeptIdAndExamine(deptId);
        }

        List<DeptVO> collect = deptList.stream().filter(
                dept -> dept.getPid().equals(deptId)).collect(Collectors.toList()
        );
        deptUserListVO.setDeptList(collect);
        deptUserListVO.setUserList(userList);
        return deptUserListVO;
    }

    /**
     * 添加用户
     *
     * @param adminUserVO 用户信息
     * @param request 请求
     * @param response 响应
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addUser(AdminUserVO adminUserVO, HttpServletRequest request, HttpServletResponse response) {
        String token = request.getHeader(BasicConstant.TOKEN_NAME);
        UserMeta userMeta;
        try {
            userMeta = new JwtCore<>(UserMeta.class).analyzeToken(token, jwtProperty.getPublicKey());
        } catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException | InstantiationException e) {
            throw new AuthorizationException(ResultCode.AuthorizationResultCode.AUTHORIZATION_LOGIN_ERR);
        }

        if (adminUserVO.getParentId() == null) {
            adminUserVO.setParentId(0L);
        }

        if (!ReUtil.isMatch(BasicConstant.DEFAULT_PASSWORD_INTENSITY, adminUserVO.getPassword())) {
            throw new BasicException(ResultCode.AdminResultCode.ADMIN_PASSWORD_INTENSITY_ERROR);
        }

        Integer count = adminUserMapper.selectCountByUsername(adminUserVO.getUsername());
        if (count > 0) {
            throw new BasicException(ResultCode.AdminResultCode.ADMIN_USER_EXIST_ERROR);
        }

        Integer nameCount = adminUserMapper.selectCountByRealname(adminUserVO.getRealname());
        if (nameCount > 0) {
            throw new BasicException(ResultCode.AdminResultCode.ADMIN_USER_REAL_NAME_EXIST_ERROR);
        }

        String salt;
        if (Algorithm.MD5.getAlgorithm().equals(passwordEncoder.getAlgorithm())) {
            salt = SaltGenerator.generate();
        } else if (Algorithm.BCRYPT.getAlgorithm().equals(passwordEncoder.getAlgorithm())) {
            salt = null;
        } else {
            salt = null;
        }

        AdminUser adminUserPO = BeanUtil.copyProperties(adminUserVO, AdminUser.class);
        adminUserPO.setCreateTime(Timestamp.from(Instant.now()));
        adminUserPO.setNum(RandomUtil.randomNumbers(15));
        adminUserPO.setMobile(adminUserPO.getUsername());
        adminUserPO.setSalt(salt);
        adminUserPO.setPassword(passwordEncoder.encode(adminUserPO.getPassword(), salt).getPasswordHash());

        Integer ignore = adminUserMapper.insertAdminUser(adminUserPO);

        adminUserConfigService.initUserConfig(adminUserPO.getUserId());
        adminUserRoleService.saveByUserId(
                adminUserPO.getUserId(),
                false,
                StrUtil.splitTrim(adminUserVO.getRoleId(), BasicConstant.SEPARATOR),
                userMeta
        );
    }
}
